<!doctype html>
<html class="no-js" lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>
  
  
  
  </title>
 <meta name="description" content="">
 <link href="atom.xml" rel="alternate" title="" type="application/atom+xml">
    <link rel="stylesheet" href="asset/css/foundation.min.css" />
    <link rel="stylesheet" href="asset/css/docs.css" />

    <script src="asset/js/vendor/modernizr.js"></script>
    <script src="asset/js/vendor/jquery.js"></script>
    <script src="asset/highlightjs/highlight.pack.js"></script>
    <link href="asset/highlightjs/styles/github.css" media="screen, projection" rel="stylesheet" type="text/css">
    <script>hljs.initHighlightingOnLoad();</script>
    
  </head>
  <body class="antialiased hide-extras">
    
    <div class="marketing off-canvas-wrap" data-offcanvas>
      <div class="inner-wrap">


<nav class="top-bar docs-bar hide-for-small" data-topbar>

<div id="header">
    <h1><a href="index.html"></a></h1>
</div>

</nav>
        <nav class="tab-bar show-for-small">
  <a href="javascript:void(0)" class="left-off-canvas-toggle menu-icon">
    <span> &nbsp; </span>
  </a>
</nav>

<aside class="left-off-canvas-menu">
      <ul class="off-canvas-list">
      <li><a href="index.html">Home</a></li>
      
        <li class="divider"></li>
        <li><label>1. Java 基础</label></li>

          
            <li><a title="1. Java 基础" href="16923474457318.html">1. Java 基础</a></li>
          

      
        <li class="divider"></li>
        <li><label>2. JCF（Java 集合）</label></li>

          
            <li><a title="2. JCF（Java 集合）" href="16923736135980.html">2. JCF（Java 集合）</a></li>
          
            <li><a title="2.4. Map - HashSet & HashMap 源码解析" href="16924335832240.html">2.4. Map - HashSet & HashMap 源码解析</a></li>
          
            <li><a title="2.5. Map - LinkedHashSet & LinkedHashMap源码解析" href="16924372183713.html">2.5. Map - LinkedHashSet & LinkedHashMap源码解析</a></li>
          
            <li><a title="2.6. Map - TreeSet & TreeMap 源码解析" href="16925007307182.html">2.6. Map - TreeSet & TreeMap 源码解析</a></li>
          

      
        <li class="divider"></li>
        <li><label>mysql</label></li>

          
            <li><a title="事务隔离" href="16925938083498.html">事务隔离</a></li>
          

      
        <li class="divider"></li>
        <li><label>常见文档</label></li>

          
            <li><a title="Paxos选举算法" href="16926055818559.html">Paxos选举算法</a></li>
          

      
      </ul>
    </aside>

<a class="exit-off-canvas" href="#"></a>

        <section id="main-content" role="main" class="scroll-container">

          <div class="row">
            <div class="large-3 medium-3 columns">
              <div class="hide-for-small">
                <div class="sidebar">
                <nav>
                  <ul id="side-nav" class="side-nav">

                    
                      <li class="side-title"><span>1. Java 基础</span></li>
                        
                          <li><a title="1. Java 基础" href="16923474457318.html">1. Java 基础</a></li>
                        

                    
                      <li class="side-title"><span>2. JCF（Java 集合）</span></li>
                        
                          <li><a title="2. JCF（Java 集合）" href="16923736135980.html">2. JCF（Java 集合）</a></li>
                        
                          <li><a title="2.4. Map - HashSet & HashMap 源码解析" href="16924335832240.html">2.4. Map - HashSet & HashMap 源码解析</a></li>
                        
                          <li><a title="2.5. Map - LinkedHashSet & LinkedHashMap源码解析" href="16924372183713.html">2.5. Map - LinkedHashSet & LinkedHashMap源码解析</a></li>
                        
                          <li><a title="2.6. Map - TreeSet & TreeMap 源码解析" href="16925007307182.html">2.6. Map - TreeSet & TreeMap 源码解析</a></li>
                        

                    
                      <li class="side-title"><span>mysql</span></li>
                        
                          <li><a title="事务隔离" href="16925938083498.html">事务隔离</a></li>
                        

                    
                      <li class="side-title"><span>常见文档</span></li>
                        
                          <li><a title="Paxos选举算法" href="16926055818559.html">Paxos选举算法</a></li>
                        

                    
                  </ul>
                </nav>
                </div>
              </div>
            </div>
            <div class="large-9 medium-9 columns">

 


	
		<div class="markdown-body">
		<h1>1. Java 基础</h1>

		<ul>
<li>
<a href="#toc_0">1.1. a = a + b 与 a += b 的区别</a>
</li>
<li>
<a href="#toc_1">1.2. 3*0.1 == 0.3 将会返回什么? true 还是 false?</a>
</li>
<li>
<a href="#toc_2">1.3. Integer的常量缓存IntegerCache</a>
</li>
<li>
<a href="#toc_3">1.4. 能在 Switch 中使用 String 吗?</a>
</li>
<li>
<a href="#toc_4">1.5. 对equals()和hashCode()的理解？</a>
</li>
<li>
<a href="#toc_5">1.6. final、finalize 和 finally 的不同之处?</a>
</li>
<li>
<a href="#toc_6">1.7. String、StringBuffer与StringBuilder的区别？</a>
</li>
<li>
<a href="#toc_7">1.8. SPI机制</a>
</li>
</ul>


<h2 id="toc_0">1.1. a = a + b 与 a += b 的区别</h2>

<ul>
<li><p>性能方面<br/>
a=a+b是加法运算 需要两次寻找地址而a+=b是增量运算有寄存器优先时 只有一次地址查找。效率方面后者略高于前者 基于现在计算机的发展可忽略不计。</p></li>
<li><p>数据类型方面<br/>
+=隐式的将加结果的类型强制转换为持有结果的类型，而前者则不会。如下：</p></li>
</ul>

<pre><code class="language-Java">byte a = 127;
byte b = 127;
b = a + b; // 编译时不通过，使用强制类型转化b=(byte)a+b可以通过
b += a; // ok

/*
《Java核心技术卷I》P43归纳过：
如果两个操作数其中有一个是double类型，另一个操作就会转换为double类型。
否则，如果其中一个操作数是float类型，另一个将会转换为float类型。
否则，如果其中一个操作数是long类型，另一个会转换为long类型。
否则，两个操作数都转换为int类型。
*/
</code></pre>

<h2 id="toc_1">1.2. 3*0.1 == 0.3 将会返回什么? true 还是 false?</h2>

<p>这个问题还可以换一下，0.1+0.2 == 0.3将会返回什么？<br/>
这个问题的解释不长，但很深。先说结果：</p>

<pre><code>在计算机中3*0.1=0.30000000000000004，很显然和0.3是不相等的，具体可以在这里
</code></pre>

<p>为什么会是这样的结果呢？如果要搞明白的话，需要了解一下《计算机组成原理》，弄明白“十进制数转化为IEEE754单精度浮点数的二进制形式”，自然就明白浮点数在计算机二进制表示过程中发生精度损失的过程了。</p>

<p>其中计算机中浮点数的表示是根据IEEE754规范来的设计的。IEEE 754有32位、64位、128位等多个版本，具体可以在：<a href="https://en.wikipedia.org/wiki/IEEE_754">https://en.wikipedia.org/wiki/IEEE_754</a> 中查看，32位的看懂了，其它的自然就很容易懂了。</p>

<p>这里推荐一个网站，仔细扒的话会有你想知道的一些：<a href="https://0.30000000000000004.com/%E3%80%82">https://0.30000000000000004.com/。</a></p>

<p>十进制数转化为IEEE754单精度浮点数的二进制形式可以看这里：<a href="https://www.bilibili.com/video/BV1tK411P7nh/">https://www.bilibili.com/video/BV1tK411P7nh/</a></p>

<h2 id="toc_2">1.3. Integer的常量缓存IntegerCache</h2>

<p>请看下面代码：<br/>
<code><br/>
Integer a = 1000, b = 1000;  <br/>
System.out.println(a == b);//结果是false<br/>
Integer c = 100, d = 100;  <br/>
System.out.println(c == d);//结果是true<br/>
</code></p>

<p>其实执行<code>Integer c = 100;</code>的时候，它实际上在内部执行的是<code>Integer i = Integer.valueOf(100);</code></p>

<p>源码中我们可以看到java.lang.Integer#valueOf(int)方法:<br/>
<code><br/>
public static Integer valueOf(int i) {<br/>
  if (i &gt;= IntegerCache.low &amp;&amp; i<br/>
      return IntegerCache.cache[i + (-IntegerCache.low)];<br/>
  return new Integer(i);<br/>
}<br/>
</code><br/>
其中的IntegerCache.low和IntegerCache.cache在源码中是：<br/>
<code><br/>
static final int low = -128;<br/>
static final int high;<br/>
static final Integer cache[];<br/>
</code></p>

<p>查看IntegerCache类源码可以得出，其中cache[]默认存放了[-128,127]的整数作为缓存，该缓存大小可以由<code>java.lang.Integer.IntegerCache.high</code>指定，该值最大可以是<code>Integer.MAX_VALUE</code>。</p>

<h2 id="toc_3">1.4. 能在 Switch 中使用 String 吗?</h2>

<p>从 Java 7 开始，我们可以在 switch case 中使用字符串。<br/>
但这仅仅是一个语法糖，内部实现在 switch 中使用字符串的 hashCode。</p>

<h2 id="toc_4">1.5. 对equals()和hashCode()的理解？</h2>

<ul>
<li><p>重写 equals 方法时，要重写 hashCode 方法<br/>
在JDK源码java.lang.Object#equals中明确指定出重写 equals 时需重写hashCode。许多容器类，如 HashMap、HashSet 都依赖于 hashcode 与 equals 的规定。</p></li>
<li><p>两个不相等的对象可能会有相同的 hashCode 吗?<br/>
有可能，两个不相等的对象可能会有相同的 hashcode 值，这就是为什么在 hashmap 中会有冲突。<br/>
只是说如果两个对象相等，必须有相同的hashcode 值，但是没有关于不相等对象的任何规定。</p></li>
</ul>

<h2 id="toc_5">1.6. final、finalize 和 finally 的不同之处?</h2>

<ul>
<li>final 是一个修饰符，可以修饰变量、方法和类。如果 final 修饰变量，意味着该变量的值在初始化后不能被改变。</li>
<li>Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的，但是什么时候调用 finalize 没有保证。</li>
<li>finally 是一个关键字，与 try 和 catch 一起用于异常的处理。finally 块一定会被执行，无论在 try 块中是否有发生异常。</li>
</ul>

<h2 id="toc_6">1.7. String、StringBuffer与StringBuilder的区别？</h2>

<ul>
<li>第一点: 可变和适用范围。String对象是不可变的，而StringBuffer和StringBuilder是可变字符序列。每次对String的操作相当于生成一个新的String对象，而对StringBuffer和StringBuilder的操作是对对象本身的操作，而不会生成新的对象，所以对于频繁改变内容的字符串避免使用String，因为频繁的生成对象将会对系统性能产生影响。</li>
<li>第二点: 线程安全。String由于有final修饰，是immutable的，安全性是简单而纯粹的。StringBuilder和StringBuffer的区别在于StringBuilder不保证同步，也就是说如果需要线程安全需要使用StringBuffer，不需要同步的StringBuilder效率更高。</li>
</ul>

<pre><code>结论：对于内容改变不频繁的使用String； 不考虑线程安全时使用StringBuilder； 考虑线程安全时使用StringBuffer。
</code></pre>

<h2 id="toc_7">1.8. SPI机制</h2>

<ul>
<li>什么是SPI机制？
SPI（Service Provider Interface），是JDK内置的一种 服务提供发现机制，可以用来启用框架扩展和替换组件，主要是被框架的开发人员使用，比如java.sql.Driver接口，其他不同厂商可以针对同一接口做出不同的实现，MySQL和PostgreSQL都有不同的实现提供给用户，而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外，在模块化设计中这个机制尤其重要，其核心思想就是 解耦。</li>
</ul>

<p>当服务的提供者提供了一种接口的实现之后，需要在classpath下的META-INF/services/目录里创建一个以服务接口命名的文件，这个文件里的内容就是这个接口的具体的实现类。当其他的程序需要这个服务的时候，就可以通过查找这个jar包（一般都是以jar包做依赖）的META-INF/services/中的配置文件，配置文件中有接口的具体实现类名，可以根据这个类名进行加载实例化，就可以使用该服务了。JDK中查找服务的实现的工具类是：java.util.ServiceLoader。</p>

<ul>
<li>SPI机制的应用？
JDBC是SPI应用的一个比较典型案例，感兴趣可以直接阅读 com.mysql.cj.jdbc.Driver 和 java.sql.DriverManager 源码很容易就能看明白，核心就在静态代码块中。</li>
</ul>


		</div>
	

 
	

 
	

 
	

 
	

 
	

 
	

  
  
</div></div>


<div class="page-bottom">
  <div class="row">
  <hr />
  <div class="small-9 columns">
  <p class="copyright">Copyright &copy; 2015
Powered by <a target="_blank" href="http://www.mweb.im">MWeb</a>,&nbsp; 
Theme used <a target="_blank" href="http://github.com">GitHub CSS</a>.</p>
  </div>
  <div class="small-3 columns">
  <p class="copyright text-right"><a href="#header">TOP</a></p>
  </div>
   
  </div>
</div>

        </section>
      </div>
    </div>
    
    
    <script src="asset/js/foundation.min.js"></script>
    <script src="asset/js/foundation/foundation.offcanvas.js"></script>
    <script>
      $(document).foundation();

     
    </script>
    


  </body>
</html>
